<script>
const defBtnStyle = {
  width: '100rpx',
  bgColor: '#f9ae3d',
  color: '#FFFFFF',
  fontSize: '28rpx',
  fontWeight: 300,
}

export default {
  name: 'NextSwipeAction',
  props: {
    btnGroup: {
      type: Array,
      default: () => {
        return [{
          name: '修改',
          style: {
            bgColor: '#f9ae3d',
          },
        }, {
          name: '删除',
          style: {
            bgColor: '#ff4d4f',
          },
        }]
      },
    },
    // 当前列索引
    index: {
      type: Number,
      require: true,
      default: 0,
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否按钮点击后自定重置
    btnClickAutoReset: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['btnClick'],
  data() {
    return {
      x: 0,
      left: 0,
      operation: 0,
      height: 0,
      screenWidth: 0,
    }
  },
  mounted() {
    this.$nextTick(() => {
      const systemInfo = uni.getSystemInfoSync()
      this.screenWidth = systemInfo.screenWidth
      this.getBtnWidth()
      this.getListHeight()
    })
  },
  methods: {
    getStyle(item) {
      const style = item.style || {}
      const styleStr = `width:${style.width || defBtnStyle.width
				};height:${this.height
				}rpx;background-color:${style.bgColor || defBtnStyle.bgColor
				};color:${style.color || defBtnStyle.color
				};font-size:${style.fontSize || defBtnStyle.fontSize
				}font-weight:${style.fontWeight || defBtnStyle.fontWeight}`
      return styleStr
    },
    btnClick(item) {
      const it = Object.assign({}, item)
      delete it.style
      this.$emit('btnClick', {
        index: this.index,
        item: it,
      })
      if (this.btnClickAutoReset)
        this.reset()
    },
    // 重置方法
    reset() {
      this.left = 0
    },
    getBtnWidth() {
      const element = uni.createSelectorQuery().in(this).select('.next-slide-right')
      element.boundingClientRect((rect) => {
        this.operation = this.px2rpx(rect.width, this.screenWidth)
      }).exec()
    },
    getListHeight() {
      const element = uni.createSelectorQuery().in(this).select('.next-slide-left')
      element.boundingClientRect((rect) => {
        this.height = this.px2rpx(rect.height, this.screenWidth)
      }).exec()
    },
    px2rpx(px, screenWidth) {
      return px / (screenWidth / 750)
    },
    ontouchstart(e) {
      if (this.disabled)
        return
      this.x = this.px2rpx(e.touches[0].clientX, this.screenWidth)
    },
    ontouchmove(e) {
      if (this.disabled)
        return
      const clientX = this.x - this.px2rpx(e.touches[0].clientX, this.screenWidth)
      if (clientX <= 0)
        this.left = 0
      else if (this.operation <= clientX)
        this.left = this.operation * -1
      else this.left = clientX * -1
    },
    ontouchend(e) {
      if (this.disabled)
        return
      const clientX = this.x - this.px2rpx(e.changedTouches[0].clientX, this.screenWidth)
      this.left = clientX > this.operation / 2 ? this.operation * -1 : 0
    },
  },
}
</script>

<template>
  <view class="next-slide" :class="{ 'next-slide-disabled': disabled }">
    <view
      class="next-slide-left" :style="`position: relative;left:${left}rpx`" @touchstart="ontouchstart"
      @touchmove="ontouchmove" @touchend="ontouchend"
    >
      <slot />
    </view>
    <view class="next-slide-right">
      <view
        v-for="(item, index) in btnGroup"
        :key="index"
        class="next-btn-item"
        :style="getStyle(item)"
        @tap.stop="btnClick(item)"
      >
        {{ item.name }}
      </view>
    </view>
  </view>
</template>

<style scoped>
	.next-slide {
		width: 100%;
		position: relative;
		overflow: hidden;
	}
	.next-slide-disabled {
		background-color: #333333;
		opacity: 0.6;
	}
	.next-slide-left {
		width: 100%;
		overflow: hidden;
		background-color: #FFFFFF;
		transition: left 0.2s ease-in-out;
		z-index: 999;
	}

	.next-slide-right {
		position: absolute;
		top: 0rpx;
		right: 0;
		z-index: 99;
		display: flex;
		align-items: center;
		justify-content: flex-end;
	}

	.next-btn-item {
		display: flex;
		align-items: center;
		justify-content: center;
	}
</style>
